using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using Three.BookStore.ProductionSystem.ShiftManagement;
using ThridGroup.ERP.EntityFrameworkCore.Configurations;
using ThridGroup.ERP.HumanResources;
using ThridGroup.ERP.OrderManagement;
using ThridGroup.ERP.ProductionSystem;
using ThridGroup.ERP.RBAC;
using ThridGroup.ERP.WarehouseManagement;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
using Volo.Abp.BlobStoring.Database.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.OpenIddict.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
using ThridGroup.ERP.SystemManagement;

namespace ThridGroup.ERP.EntityFrameworkCore;

[ReplaceDbContext(typeof(IIdentityDbContext))]
[ReplaceDbContext(typeof(ITenantManagementDbContext))]
[ConnectionStringName("Default")]
public class ERPDbContext :
    AbpDbContext<ERPDbContext>,
    ITenantManagementDbContext,
    IIdentityDbContext
{
    /* Add DbSet properties for your Aggregate Roots / Entities here. */


    #region Entities from the modules

    /* Notice: We only implemented IIdentityProDbContext and ISaasDbContext
     * and replaced them for this DbContext. This allows you to perform JOIN
     * queries for the entities of these modules over the repositories easily. You
     * typically don't need that for other modules. But, if you need, you can
     * implement the DbContext interface of the needed module and use ReplaceDbContext
     * attribute just like IIdentityProDbContext and ISaasDbContext.
     *
     * More info: Replacing a DbContext of a module ensures that the related module
     * uses this DbContext on runtime. Otherwise, it will use its own DbContext class.
     */

    // Identity
    public DbSet<IdentityUser> Users { get; set; }
    public DbSet<IdentityRole> Roles { get; set; }
    public DbSet<IdentityClaimType> ClaimTypes { get; set; }
    public DbSet<OrganizationUnit> OrganizationUnits { get; set; }
    public DbSet<IdentitySecurityLog> SecurityLogs { get; set; }
    public DbSet<IdentityLinkUser> LinkUsers { get; set; }
    public DbSet<IdentityUserDelegation> UserDelegations { get; set; }
    public DbSet<IdentitySession> Sessions { get; set; }
    // Tenant Management
    public DbSet<Tenant> Tenants { get; set; }
    public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; }
    /// <summary>
    /// 装箱明细表
    /// </summary>
    public DbSet<PackingDetailsModelS> PackingDetailsModelS { get; set; }
    /// <summary>
    /// 物料入库表
    /// </summary>
    public DbSet<MaterialReceiptLineModelS> MaterialReceiptLineModelS { get; set; }

    public DbSet<HolidaySettingModel> HolidaySettingModel { get; set; }

    #endregion


    #region 
    //============================RBAC============================
    public DbSet<Permission> permissions { get; set; }
    public DbSet<Role> roles { get; set; }
    public DbSet<RolePermission> rolePermissions { get; set; }
    public DbSet<User> users { get; set; }
    public DbSet<UserRole> userRoles { get; set; }

    //public DbSet<StudentModel> studentModel { get; set; }

    //// =====================================   wnn
    ///// <summary>
    ///ͻ
    /// </summary>
    public DbSet<DeliveryNoteModel> deliveryNoteModels { get; set; }
    /// <summary>
    ///۶
    /// </summary>
    public DbSet<SalesOrderModel> salesOrderModels { get; set; }

    ////============================ϵͳ============================
    //public DbSet<StudentModel> studentModels { get; set; }
    /// <summary>
    /// Թ
    /// </summary>
    public DbSet<InterviewMenagement> interviewMenagements { get; set; }
    /// <summary>
    /// ְ
    /// </summary>
    public DbSet<JobGradeManagement> jobGradeManagements { get; set; }
    /// <summary>
    /// ˲ŵǼǱ 
    /// </summary>
    public DbSet<TalentRegistration> talentRegistrations { get; set; }
    /// <summary>
    /// ְ
    /// </summary>
    public DbSet<OnboardingReviewModel> OnboardingReview { get; set; }

    //++++++++++++++++++++++++++++++

    /// <summary>
    ///  -xjb
    /// </summary>
    public DbSet<CodingmanagementModel> Codingmanagement { get; set; }

    /// <summary>
    ///-xjb
    /// </summary>
    public DbSet<InventoryModel> Inventory { get; set; }


    /// <summary>
    /// װ䵥  װ䵥  wnn
    /// </summary>
    public DbSet<PackingModelS> Packing { get; set; }

    /// <summary>
    /// ɹ-xjb
    /// </summary>
    public DbSet<ProcurementModelS> Procurement { get; set; }

    /// <summary>
    /// ۳-xjb
    /// </summary>
    public DbSet<SaleModel> Sale { get; set; }

    /// <summary>
    /// ˻-xjb 
    /// </summary>
    public DbSet<SalesReturnsModel> SalesReturns { get; set; }


    /// <summary>
    /// Ӧ˻-xjb
    /// </summary>
    public DbSet<SupplierReturnsModel> SupplierReturns { get; set; }

    /// <summary>
    /// 排班日历
    /// </summary>
    public DbSet<ShiftScheduleModel> ShiftScheduleModels { get; set; }
    /// <summary>
    /// תƵ-xjb
    /// </summary>
    public DbSet<TransferTransfersModel> TransferTransfers { get; set; }

    /// <summary>
    /// 仓库设置-xjb
    /// </summary>
    public DbSet<WarehouseSettingModel> WarehouseSetting { get; set; }
    
    /// <summary>
    /// 库区设置
    /// </summary>
    public DbSet<WarehouseAreaSettingModel> WarehouseAreaSetting { get; set; }
    
    /// <summary>
    /// 库位设置
    /// </summary>
    public DbSet<WarehouseLocationSettingModel> WarehouseLocationSettings { get; set; }
    
    /// <summary>
    /// 系统版本
    /// </summary>
    public DbSet<SystemVersionModel> SystemVersions { get; set; }

    /// <summary>
    /// 产品入库
    /// </summary>
    public DbSet<ProductsInbound> productsInbounds { get; set; }

    /// <summary>
    /// Э
    /// </summary>
    public DbSet<OutsourcingWarehousing> outsourcingWarehousings { get; set; }
    /// <summary>
    /// Э
    /// </summary>
    public DbSet<OutsourcingMaterial> outsourcingMaterials { get; set; }
    /// <summary>
    /// ̵
    /// </summary>
    public DbSet<InventoryCounts> inventoryCounts { get; set; }

    //===========================����ϵͳ===============wnn
    /// <summary>
    ///�Ű�ƻ�
    /// </summary>
    public DbSet<CrewScheduling> crewSchedulings { get; set; }

    /// <summary>
    ///�豸̨��
    /// </summary>
    public DbSet<DeviceLedgerModel> deviceLedgerModels { get; set; }
    /// <summary>
    ///��챣���ƻ�
    /// </summary>
    public DbSet<EquipmentInspectionModel> equipmentInspectionModels { get; set; }

    /// <summary>
    ///�豸����
    /// </summary>
    public DbSet<EquipmentTypeModel> equipmentTypeModels { get; set; }

    /// <summary>
    ///点检保养计划
    /// </summary>
    public DbSet<MaintenanceplanModel> maintenanceplanModels { get; set; }

    /// <summary>
    ///设备维修单
    /// </summary>
    public DbSet<RepairOrderModelS> repairOrderModels { get; set; }

    /// <summary>
    ///��������
    /// </summary>
    public DbSet<TeamModel> teamModels { get; set; }

    /// <summary>
    ///��װ�о��嵥  ̨��
    /// </summary>
    public DbSet<ToolingFixtureRecordModel> toolingFixtureRecordModels { get; set; }
    /// <summary>
    ///��װ�о����� 
    /// </summary>
    public DbSet<ToolingFixtureTypeModel> toolingFixtureTypeModels { get; set; }

    /// <summary>
    /// ���ϲ�Ʒ����--LSS
    /// </summary>
    public DbSet<MaterialType> MaterialTypes { get; set; }
    /// <summary>
    /// ���㵥λ
    /// </summary>
    public DbSet<CalculateUnit> CalculateUnits { get; set; }
    /// <summary>
    /// ����
    /// </summary>
    public DbSet<MaterielModel> MaterielModels { get; set; }
    /// <summary>
    /// �ͻ�����
    /// </summary>
    public DbSet<CustomerModel> CustomerModels { get; set; }
    /// <summary>
    /// ��Ӧ�̹���
    /// </summary>
    public DbSet<SupplierModel> SupplierModels { get; set; }
    /// <summary>
    /// ����
    /// </summary>
    public DbSet<ProcedureModel> ProcedureModels { get; set; }
    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<Workmanship> Workmanships { get; set; }
    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<Workshop> Workshops { get; set; }
    /// <summary>
    /// �ͻ�����
    /// </summary>
    public DbSet<CustomerOrder> CustomerOrders { get; set; }
    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<Production> Productions { get; set; }
    /// <summary>
    /// �����Ų�
    /// </summary>
    public DbSet<ProductionScheduling> ProductionSchedulings { get; set; }
    /// <summary>
    /// �����ɵ�
    /// </summary>
    public DbSet<OrderDispatch> OrderDispatchs { get; set; }
    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<ProductionMaterial> ProductionMaterials { get; set; }
    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<ProductionReporting> ProductionReportings { get; set; }
    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<ProductionMaterialReturn> ProductionMaterialReturns { get; set; }
    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<ProductionWasteOrder> ProductionWasteOrders { get; set; }
    /// <summary>
    /// 待检任务
    /// </summary>
    public DbSet<PendingTasks> PendingTasks { get; set; }
    /// <summary>
    /// 来料检验
    /// </summary>
    public DbSet<IncomingInspection> IncomingInspections { get; set; }
    /// <summary>
    /// 出货检验
    /// </summary>
    public DbSet<OutgoingInspection> OutgoingInspections { get; set; }

    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<ItemSettings> itemSettings { get; set; }

    /// <summary>
    /// ��������
    /// </summary>
    public DbSet<SailingsModel> sailingsModels { get; set; }

    /// <summary>
    /// 采购入库
    /// </summary>
    public DbSet<ProcurementModelS> ProcurementModelS { get; set; }
    /// <summary>
    /// 装箱
    /// </summary>
    public DbSet<PackingModelS> PackingModelS { get; set; }

    #endregion


    public ERPDbContext(DbContextOptions<ERPDbContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        /* Include modules to your migration db context */

        builder.ConfigurePermissionManagement();
        builder.ConfigureSettingManagement();
        builder.ConfigureBackgroundJobs();
        builder.ConfigureAuditLogging();
        builder.ConfigureFeatureManagement();
        builder.ConfigureIdentity();
        builder.ConfigureOpenIddict();
        builder.ConfigureTenantManagement();
        builder.ConfigureBlobStoring();
        
        /* Configure your own tables/entities inside here */

        // 应用 MaterialType 实体配置
        builder.ApplyConfiguration(new MaterialTypeConfiguration());

        // 应用 Workshop 实体配置
        builder.ApplyConfiguration(new WorkshopConfiguration());

        // 配置物料分类实体
        builder.Entity<MaterialType>(b =>
        {
            b.ToTable("MaterialTypes");
            b.ConfigureByConvention();

            b.Property(x => x.MaterialTypeName)
                .IsRequired()
                .HasMaxLength(100);

            b.Property(x => x.ParentId)
                .IsRequired();

            b.Property(x => x.Index)
                .IsRequired();

            b.Property(x => x.IsEnable)
                .IsRequired();

            b.Property(x => x.CreateTime)
                .IsRequired();

            b.Property(x => x.IsDeleted)
                .IsRequired();
        });

        // 配置出货检验实体表名
        builder.Entity<OutgoingInspection>(b =>
        {
            b.ToTable("outgoinginspection");
            b.ConfigureByConvention();
            
            // 显式配置主键并设置为自动生成
            b.HasKey(x => x.Id);
            b.Property(x => x.Id)
                .HasColumnName("id")
                .ValueGeneratedOnAdd(); // 设置为自动生成
            
            // 配置其他属性的列名映射（确保与数据库一致）
            b.Property(x => x.OutgoingCode).HasColumnName("outgoingcode").IsRequired().HasMaxLength(50);
            b.Property(x => x.OutgoingName).HasColumnName("outgoingname").IsRequired().HasMaxLength(100);
            b.Property(x => x.Customer).HasColumnName("customer").HasMaxLength(100);
            b.Property(x => x.Batch).HasColumnName("batch").HasMaxLength(50);
            b.Property(x => x.ProductCode).HasColumnName("productcode").HasMaxLength(50);
            b.Property(x => x.ProductName).HasColumnName("productname").HasMaxLength(100);
            b.Property(x => x.Specifications).HasColumnName("specifications").HasMaxLength(200);
            b.Property(x => x.Unitt).HasColumnName("unitt").HasMaxLength(20);
            b.Property(x => x.Send).HasColumnName("send");
            b.Property(x => x.TestingNum).HasColumnName("testingnum");
            b.Property(x => x.UnqualifiedNum).HasColumnName("unqualifiednum");
            b.Property(x => x.TestingResult).HasColumnName("testingresult").HasMaxLength(50);
            b.Property(x => x.ShipmentDate).HasColumnName("shipmentdate");
            b.Property(x => x.TestingDate).HasColumnName("testingdate");
            b.Property(x => x.TestingPerson).HasColumnName("testingperson").HasMaxLength(50);
            b.Property(x => x.State).HasColumnName("state");
            // b.Property(x => x.Remarks).HasColumnName("remarks").HasMaxLength(500); // 暂时注释，待添加数据库字段后启用
        });

        // 配置仓库设置实体表名
        builder.Entity<WarehouseSettingModel>(b =>
        {
            b.ToTable("WarehouseSetting");
            b.ConfigureByConvention();
            
            // 显式配置主键
            b.HasKey(x => x.Id);
            b.Property(x => x.Id)
                .HasColumnName("Id")
                .ValueGeneratedOnAdd();
            
            // 配置其他属性的列名映射（确保与数据库一致）
            b.Property(x => x.DepotCode).HasColumnName("DepotCode").IsRequired();
            b.Property(x => x.DepotName).HasColumnName("DepotName").IsRequired();
            b.Property(x => x.Location).HasColumnName("Location").IsRequired();
            b.Property(x => x.Area).HasColumnName("Area").IsRequired();
            b.Property(x => x.Head).HasColumnName("Head").IsRequired();
            b.Property(x => x.Remark).HasColumnName("Remark").IsRequired();
        });

        // 配置库区设置实体表名
        builder.Entity<WarehouseAreaSettingModel>(b =>
        {
            b.ToTable("WarehouseAreaSetting");
            b.ConfigureByConvention();
            
            // 显式配置主键
            b.HasKey(x => x.Id);
            b.Property(x => x.Id)
                .HasColumnName("Id")
                .ValueGeneratedOnAdd();
            
            // 配置其他属性的列名映射（确保与数据库一致）
            b.Property(x => x.AreaCode).HasColumnName("WarehouseAreaCode").IsRequired();
            b.Property(x => x.AreaName).HasColumnName("WarehouseAreaName").IsRequired();
            b.Property(x => x.WarehouseId).HasColumnName("WarehouseId");
            b.Property(x => x.Area).HasColumnName("Area");
            b.Property(x => x.Remark).HasColumnName("Remark");
            
            // 如果数据库中没有以下字段，需要将它们标记为忽略
            b.Ignore(x => x.WarehouseName);
            b.Ignore(x => x.Location);
            b.Ignore(x => x.ResponsiblePerson);
            b.Ignore(x => x.AreaType);
            b.Ignore(x => x.StorageType);
            b.Ignore(x => x.TemperatureRequirement);
            b.Ignore(x => x.HumidityRequirement);
            b.Ignore(x => x.MaxCapacity);
            b.Ignore(x => x.CurrentUsage);
            b.Ignore(x => x.Status);
            b.Ignore(x => x.CreatedTime);
            b.Ignore(x => x.UpdatedTime);
        });

        // 配置库位设置实体表名
        builder.Entity<WarehouseLocationSettingModel>(b =>
        {
            b.ToTable("WarehouseLocationSetting");
            b.ConfigureByConvention();
            
            b.HasKey(x => x.Id);
            
            b.Property(x => x.LocationCode).IsRequired().HasMaxLength(50);
            b.Property(x => x.LocationName).IsRequired().HasMaxLength(100);
            b.Property(x => x.WarehouseAreaId).IsRequired();
            b.Property(x => x.Area).HasColumnType("decimal(10,2)").HasDefaultValue(0);
            b.Property(x => x.MaxCapacity).HasColumnType("decimal(10,2)").HasDefaultValue(0);
            b.Property(x => x.LocationX).HasDefaultValue(0);
            b.Property(x => x.LocationY).HasDefaultValue(0);
            b.Property(x => x.LocationZ).HasDefaultValue(0);
            b.Property(x => x.IsUsed).HasDefaultValue(false);
            b.Property(x => x.Remark).HasMaxLength(500);
            b.Property(x => x.CreatedTime).HasDefaultValueSql("CURRENT_TIMESTAMP");
            
            b.HasIndex(x => x.LocationCode);
            b.HasIndex(x => x.WarehouseAreaId);
            
            b.HasOne(x => x.WarehouseArea)
                .WithMany()
                .HasForeignKey(x => x.WarehouseAreaId)
                .OnDelete(DeleteBehavior.Cascade);
        });

        // 配置系统版本实体表名
        builder.Entity<SystemVersionModel>(b =>
        {
            b.ToTable("SystemVersion");
            b.ConfigureByConvention();
            
            b.HasKey(x => x.Id);
            
            b.Property(x => x.VersionNumber).IsRequired().HasMaxLength(50);
            b.Property(x => x.Description).HasMaxLength(200);
        });
    }
}
